package com.googlecode.maratische.google.gui;

import static com.googlecode.maratische.google.MainController.getMainController;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
import java.sql.SQLException;
import java.util.EventObject;
import java.util.List;

import javax.swing.AbstractCellEditor;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.JWindow;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreeCellEditor;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreePath;

import com.googlecode.maratische.google.BaseException;
import com.googlecode.maratische.google.DaoAction;
import com.googlecode.maratische.google.model.Feed;

public class WindowTreeAddNewFeeds extends JWindow {
	private static final long serialVersionUID = 8484938922872464234L;
//	private static Logger logger = Logger.getLogger(WindowTreeAddNewFeeds.class.getName());
	FeedNode rootNode = null;

	public WindowTreeAddNewFeeds(Point parentPosition, Dimension parentSize) throws SQLException, BaseException {
		parentPosition.move((int) (parentPosition.x + parentSize.getWidth() / 2), parentPosition.y);
		parentSize.setSize((int) (parentSize.getWidth() / 2), parentSize.getHeight() * 3);
		setLocation(parentPosition);
		setSize(parentSize);
		getContentPane().setBackground(Color.yellow);
		setVisible(true);

		setLayout(new BorderLayout());

		JPanel panelbutton = new JPanel();
		panelbutton.setLayout(new FlowLayout(FlowLayout.RIGHT));
		JButton buttonSave = new JButton(getBundleMessage("button.save"));
		panelbutton.add(buttonSave);
		buttonSave.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				saveAction();
				WindowTreeAddNewFeeds.this.dispose();
			}
		});
		JButton buttonCancel = new JButton(getBundleMessage("button.cancel"));
		panelbutton.add(buttonCancel);
		buttonCancel.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				WindowTreeAddNewFeeds.this.dispose();
			}
		});

		add(panelbutton, BorderLayout.NORTH);

		/**
		 * Надо банально получить наше же дерево элементов Feed, но только тех,
		 * у кого offlineSupport is null
		 */

		rootNode = new FeedNode();
		List<Feed> rootFeeds = DaoAction.getDaoAction().getFeedDao().findByParentId(0);
		
		for (Feed feed : rootFeeds) {
			FeedNode feedNode = new FeedNode(feed);
			List<Feed> childFeeds = DaoAction.getDaoAction().getFeedDao().findByParentId(feed.getId());
			if (childFeeds.size() >0) {
				boolean exist = false;
				for (Feed child : childFeeds) {
					if (child.getOfflineSupport() == null && child.getUnreadItems()>0) {
						child.setOfflineSupport(Boolean.TRUE);
						feedNode.add(new FeedNode(child));
						exist = true;
					}
				}
				if (exist) {
					rootNode.add(feedNode);
				}
			} else if (feed.getOfflineSupport() == null && feed.getUnreadItems()>0) {
				feedNode.setOfflineSupport(Boolean.TRUE);
				rootNode.add(feedNode);
			}
		}
		
		JTree tree = new JTree(rootNode);

		CheckBoxNodeRenderer renderer = new CheckBoxNodeRenderer();
		tree.setCellRenderer(renderer);

		tree.setCellEditor(new CheckBoxNodeEditor(tree));
		tree.setEditable(true);

		JScrollPane scrollPane = new JScrollPane(tree);
		add(scrollPane, BorderLayout.CENTER);
	}

	public String getBundleMessage(String message) {
		return getMainController().getBundleMessage(message);
	}

	/**
	 * находим все помеченные ленты и сохраняем их с статусом
	 */
	private void saveAction() {
		if (rootNode != null) {
			if (rootNode.getChildCount()>0) {
				for (int i=0;i<rootNode.getChildCount();i++) {
					if (rootNode.getChildAt(i) instanceof FeedNode) {
						FeedNode feedNode = (FeedNode)rootNode.getChildAt(i);
						if (feedNode.isFolder()) {
							if (feedNode.getChildCount()>0) {
								for (int ii=0;ii<feedNode.getChildCount();ii++) {
									if (feedNode.getChildAt(ii) instanceof FeedNode) {
										FeedNode childNode = (FeedNode)feedNode.getChildAt(ii);
										getMainController().changeOfflineSupportForSelectedFeed(childNode.getFeed(),childNode.isOfflineSupport());
									}
								}
							}
						} else {
							if (feedNode.isOfflineSupport()) {
								getMainController().changeOfflineSupportForSelectedFeed(feedNode.getFeed(),feedNode.isOfflineSupport());
							}
						}
					}
				}
			}
		}
	}
}

class CheckBoxNodeRenderer implements TreeCellRenderer {
	private JCheckBox leafRenderer = new JCheckBox();

	private DefaultTreeCellRenderer nonLeafRenderer = new DefaultTreeCellRenderer();

	Color selectionBorderColor, selectionForeground, selectionBackground, textForeground, textBackground;

	protected JCheckBox getLeafRenderer() {
		return leafRenderer;
	}

	public CheckBoxNodeRenderer() {
		Font fontValue;
		fontValue = UIManager.getFont("Tree.font");
		if (fontValue != null) {
			leafRenderer.setFont(fontValue);
		}
		Boolean booleanValue = (Boolean) UIManager.get("Tree.drawsFocusBorderAroundIcon");
		leafRenderer.setFocusPainted((booleanValue != null) && (booleanValue.booleanValue()));

		selectionBorderColor = UIManager.getColor("Tree.selectionBorderColor");
		selectionForeground = UIManager.getColor("Tree.selectionForeground");
		selectionBackground = UIManager.getColor("Tree.selectionBackground");
		textForeground = UIManager.getColor("Tree.textForeground");
		textBackground = UIManager.getColor("Tree.textBackground");
	}

	public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row,
			boolean hasFocus) {

		Component returnValue;
		if (leaf) {
			String stringValue = tree.convertValueToText(value, selected, expanded, leaf, row, false);
			leafRenderer.setText(stringValue);
			leafRenderer.setSelected(true);

			leafRenderer.setEnabled(tree.isEnabled());

			if (selected) {
				leafRenderer.setForeground(selectionForeground);
				leafRenderer.setBackground(selectionBackground);
			} else {
				leafRenderer.setForeground(textForeground);
				leafRenderer.setBackground(textBackground);
			}

			if ((value != null) && (value instanceof DefaultMutableTreeNode)) {
				Object userObject = ((DefaultMutableTreeNode) value).getUserObject();
				if (userObject instanceof FeedNode) {
					FeedNode node = (FeedNode)userObject;
					leafRenderer.setText(node.toString());
					leafRenderer.setSelected(node.isOfflineSupport());
				}
			}
			returnValue = leafRenderer;
		} else {
			returnValue = nonLeafRenderer.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
		}
		return returnValue;
	}
}

class CheckBoxNodeEditor extends AbstractCellEditor implements TreeCellEditor {

	private static final long serialVersionUID = -5489953392580038058L;

	CheckBoxNodeRenderer renderer = new CheckBoxNodeRenderer();

	ChangeEvent changeEvent = null;
	JTree tree;
	private FeedNode selectedNode = null;

	public CheckBoxNodeEditor(JTree tree) {
		this.tree = tree;
	}

	public Object getCellEditorValue() {
		JCheckBox checkbox = renderer.getLeafRenderer();
		if (this.selectedNode != null) {
			this.selectedNode.setOfflineSupport(checkbox.isSelected());
		}
		return this.selectedNode;
	}

	public boolean isCellEditable(EventObject event) {
		boolean returnValue = false;
		this.selectedNode = null;
		if (event instanceof MouseEvent) {
			MouseEvent mouseEvent = (MouseEvent) event;
			TreePath path = tree.getPathForLocation(mouseEvent.getX(), mouseEvent.getY());
			if (path != null) {
				Object node = path.getLastPathComponent();
				if ((node != null) && (node instanceof DefaultMutableTreeNode)) {
					DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) node;
//					Object userObject = treeNode.getUserObject();
					returnValue = treeNode.isLeaf();
//					returnValue = ((treeNode.isLeaf()) && (userObject instanceof FeedNode));
					if (node instanceof FeedNode) {
						this.selectedNode = (FeedNode)node;
					}
				}
			}
		}
		return returnValue;
	}

	public Component getTreeCellEditorComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row) {

		Component editor = renderer.getTreeCellRendererComponent(tree, value, true, expanded, leaf, row, true);

		// editor always selected / focused
		ItemListener itemListener = new ItemListener() {
			public void itemStateChanged(ItemEvent itemEvent) {
				if (stopCellEditing()) {
					fireEditingStopped();
				}
			}
		};
		if (editor instanceof JCheckBox) {
			((JCheckBox) editor).addItemListener(itemListener);
		}

		return editor;
	}
}
